unit Main;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants,
  System.Classes, Vcl.Graphics,
  Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.ComCtrls, Vcl.StdCtrls, Vcl.ImgList;

type
  TfrmMainStyles = class(TForm)
    pgc1: TPageControl;
    ts1: TTabSheet;
    lstLoadedStyles: TListBox;
    btnBtnApply: TButton;
    ts2: TTabSheet;
    btnBtnRegister: TButton;
    lstDiskStyles: TListBox;
    ts3: TTabSheet;
    lv1: TListView;
    btn1: TButton;
    il1: TImageList;
    procedure btnBtnApplyClick(Sender: TObject);
    procedure btnBtnRegisterClick(Sender: TObject);
    procedure btn1Click(Sender: TObject);
    procedure FormCreate(Sender: TObject);
  private
    procedure LoadRegisteredStyles;
    procedure LoadStylesFromDisk;
    procedure RegisterAndSetStyleFromDisk(const StyleFileName: string);
    procedure SetStyleByIndex(Index: Integer);

    procedure GetStyleInfo;

    procedure SetSkin(skinName: string);
    procedure GetSkin;
  public
    { Public declarations }
  end;

var
  frmMainStyles: TfrmMainStyles;

implementation

uses
  TypInfo,
  System.IOUtils,
  Vcl.Styles,
  Vcl.Themes,
  Inifiles;
{$R *.dfm}

{ TfrmMainStyles }
procedure CreateArrayBitmap(Width, Height: Word; Colors: Array of TColor;
  var bmp: TBitmap);
Var
  i: Integer;
  w: Integer;
begin
  bmp.PixelFormat := pf24bit;
  bmp.Width := Width;
  bmp.Height := Height;
  bmp.Canvas.Brush.Color := clBlack;
  bmp.Canvas.FillRect(Rect(0, 0, Width, Height));

  w := (Width - 2) div (High(Colors) + 1);
  for i := 0 to High(Colors) do
  begin
    bmp.Canvas.Brush.Color := Colors[i];
    // bmp.Canvas.FillRect(Rect((w*i),0, w*(i+1), Height));
    bmp.Canvas.FillRect(Rect((w * i) + 1, 1, w * (i + 1) + 1, Height - 1))
  end;
end;

procedure TfrmMainStyles.btn1Click(Sender: TObject);
begin
  GetStyleInfo;
end;

procedure TfrmMainStyles.btnBtnApplyClick(Sender: TObject);
begin
  if lstLoadedStyles.ItemIndex >= 0 then
    SetStyleByIndex(lstLoadedStyles.ItemIndex);
  SetSkin(lstLoadedStyles.Items[lstLoadedStyles.ItemIndex]);
end;

procedure TfrmMainStyles.btnBtnRegisterClick(Sender: TObject);
begin
  if lstDiskStyles.ItemIndex >= 0 then
  begin
    RegisterAndSetStyleFromDisk(lstDiskStyles.Items[lstDiskStyles.ItemIndex]);

    SetSkin(lstDiskStyles.Items[lstDiskStyles.ItemIndex]);

    lstDiskStyles.Items.Delete(lstDiskStyles.ItemIndex);
    LoadRegisteredStyles;
  end;

end;

procedure TfrmMainStyles.FormCreate(Sender: TObject);
begin
  LoadRegisteredStyles;
  LoadStylesFromDisk;
  lstLoadedStyles.ItemIndex := 0;
  GetSkin;
end;

procedure TfrmMainStyles.GetSkin;
var
  skinpath, skinName: string;
  skinconfig: TIniFile;
  bb: Boolean;
  function Trimplace(str: string): string;
  var
    tmp: string;
    p: Integer;
  begin
    tmp := Trim(str);
    while Pos(' ', tmp) > 0 do
    begin
      p := Pos(' ', tmp);
      tmp := Copy(tmp, 1, p - 1) + Copy(tmp, p + 1, Length(tmp) - p);
    end;
    Result := tmp;
  end;

begin
  skinconfig := TIniFile.Create(ExtractFilePath(ParamStr(0)) + 'config.ini');
  skinpath := ExtractFilePath(ParamStr(0)) + 'config.ini';
  skinpath := skinconfig.ReadString('Skin', 'SkinName', '');
  bb := False;
  try
    for skinName in TStyleManager.StyleNames do
      if skinName = skinpath then
      begin
        TStyleManager.SetStyle(skinName);
        bb := True;
        Break;
      end;
    if not bb then
    begin
      skinpath := Trimplace(skinpath);
      RegisterAndSetStyleFromDisk(ExtractFilePath(Application.ExeName) +
        'styles\' + skinpath + '.vsf');
    end;
  finally
    FreeAndNil(skinconfig);
  end;
end;

procedure TfrmMainStyles.GetStyleInfo;
Var
  StyleName: string;

  StyleColor: TStyleColor;
  AColor: TColor;
  bmp: TBitmap;
  Item: TListItem;
begin
  StyleName := lstLoadedStyles.Items[lstLoadedStyles.ItemIndex];

  lv1.Items.Clear;
  il1.Clear;
  for StyleColor := scBorder to scWindow do
  begin
    AColor := TStyleManager.Style[StyleName].GetStyleColor(StyleColor);
    bmp := TBitmap.Create;
    try
      CreateArrayBitmap(16, 16, [AColor], bmp);
      il1.Add(bmp, nil);
      Item := lv1.Items.Add;
      Item.ImageIndex := il1.Count - 1;
      Item.Caption := GetEnumName(TypeInfo(TStyleColor), Ord(StyleColor));
      Item.SubItems.Add(ColorToString(AColor));
    finally
      bmp.Free;
    end;
  end;

end;

procedure TfrmMainStyles.LoadRegisteredStyles;
Var
  Name: string;
begin
  for Name in TStyleManager.StyleNames do
    if lstLoadedStyles.Items.IndexOf(Name) = -1 then
      lstLoadedStyles.Items.Add(Name);
end;

procedure TfrmMainStyles.LoadStylesFromDisk;
Var
  FileName: string;
begin
  for FileName in TDirectory.GetFiles
    (IncludeTrailingPathDelimiter(ExtractFilePath(ParamStr(0))) + 'Styles',
    '*' + TStyleEngine.FileExtension) do
    lstDiskStyles.Items.Add(FileName);
end;

procedure TfrmMainStyles.RegisterAndSetStyleFromDisk
  (const StyleFileName: string);
begin
  TStyleManager.SetStyle(TStyleManager.LoadFromFile(StyleFileName))
end;

procedure TfrmMainStyles.SetSkin(skinName: string);
var
  skinconfig: TIniFile;
begin
  skinconfig := TIniFile.Create(ExtractFilePath(ParamStr(0)) + 'config.ini');
  try
    skinconfig.WriteString('Skin', 'SkinName', skinName);
  finally
    FreeAndNil(skinconfig);
  end;

end;

procedure TfrmMainStyles.SetStyleByIndex(Index: Integer);
begin
  TStyleManager.SetStyle(lstLoadedStyles.Items[Index]);
end;

end.
